home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / etc / mktemp.c < prev    next >
C/C++ Source or Header  |  1989-07-21  |  2KB  |  106 lines

  1. /*
  2.  * Copyright (c) 1987 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific written prior permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #if defined(LIBC_SCCS) && !defined(lint)
  14. static char sccsid[] = "@(#)mktemp.c    5.6 (Berkeley) 5/23/88";
  15. #endif /* LIBC_SCCS and not lint */
  16.  
  17. #include <sys/types.h>
  18. #include <sys/file.h>
  19. #include <sys/stat.h>
  20. #include <errno.h>
  21. #include <stdio.h>
  22. #include <ctype.h>
  23.  
  24. #define    YES    1
  25. #define    NO    0
  26.  
  27. static int _gettemp();
  28.  
  29. int
  30. mkstemp(as)
  31.     char    *as;
  32. {
  33.     int    fd;
  34.  
  35.     return (_gettemp(as, &fd) ? fd : -1);
  36. }
  37.  
  38. char *
  39. mktemp(as)
  40.     char    *as;
  41. {
  42.     return(_gettemp(as, (int *)NULL) ? as : (char *)NULL);
  43. }
  44.  
  45. static int
  46. _gettemp(as, doopen)
  47.     char    *as;
  48.     register int    *doopen;
  49. {
  50.     extern int    errno;
  51.     register char    *start, *trv;
  52.     struct stat    sbuf;
  53.     u_int    pid;
  54.  
  55.     pid = getpid();
  56.  
  57.     /* extra X's get set to 0's */
  58.     for (trv = as; *trv; ++trv);
  59.     while (*--trv == 'X') {
  60.         *trv = (pid % 10) + '0';
  61.         pid /= 10;
  62.     }
  63.  
  64.     /*
  65.      * check for write permission on target directory; if you have
  66.      * six X's and you can't write the directory, this will run for
  67.      * a *very* long time.
  68.      */
  69.     for (start = ++trv; trv > as && *trv != '/'; --trv);
  70.     if (*trv == '/') {
  71.         *trv = '\0';
  72.         if (stat(as, &sbuf) || !(sbuf.st_mode & S_IFDIR))
  73.             return(NO);
  74.         *trv = '/';
  75.     }
  76.     else if (stat(".", &sbuf) == -1)
  77.         return(NO);
  78.  
  79.     for (;;) {
  80.         if (doopen) {
  81.             if ((*doopen = open(as, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
  82.             return(YES);
  83.             if (errno != EEXIST)
  84.             return(NO);
  85.         }
  86.         else if (stat(as, &sbuf))
  87.             return(errno == ENOENT ? YES : NO);
  88.  
  89.         /* tricky little algorithm for backward compatibility */
  90.         for (trv = start;;) {
  91.             if (!*trv)
  92.                 return(NO);
  93.             if (*trv == 'z')
  94.                 *trv++ = 'a';
  95.             else {
  96.                 if (isdigit(*trv))
  97.                     *trv = 'a';
  98.                 else
  99.                     ++*trv;
  100.                 break;
  101.             }
  102.         }
  103.     }
  104.     /*NOTREACHED*/
  105. }
  106.